package com.yami.shop.api.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yami.shop.bean.model.*;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.i18n.I18nMessage;
import com.yami.shop.common.response.ServerResponseEntity;
import com.yami.shop.common.util.DataWebService;
import com.yami.shop.common.util.PageParam;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.personnft.common.controller.BaseController;
import com.yami.shop.service.ChannelUserRelationRecordService;
import com.yami.shop.service.*;
import groovy.lang.Tuple;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/userNftAddressBook")
public class UserNftAddressBookController extends BaseController {

    @Autowired
    private UserNftAddressBookService userNftAddressBookService;
    @Autowired
    private DataWebService dataWebService;
    @Autowired
    private ShopConfig shopConfig;
    @Autowired
    private BlockchainService blockchainService;
    @Autowired
    private ShopDetailService shopDetailService;
    @Autowired
    private ChannelUserRelationRecordService channelUserRelationRecordService;
    @Autowired
    private UserService userService;
    @Autowired
    private BlockchainShopService blockchainShopService;
    /**
     *
     * @param page
     * @param userNftAddressBook
     * @return
     */
    @GetMapping("/getAddressBookList")
    @Operation(summary =  "分页查询", description = "分页查询")
    public ServerResponseEntity<IPage<UserNftAddressBook>> getAddressBookList(PageParam<UserNftAddressBook> page, UserNftAddressBook userNftAddressBook) {
        if(userNftAddressBook.getFlag()){
            Tuple<String> tuple = this.getChannelInfo(userNftAddressBook.getUserId());
            userNftAddressBook.setChannelCode(tuple.get(0));
            userNftAddressBook.setNftCode(tuple.get(2));
            userNftAddressBook.setType(tuple.get(3));
        }
        IPage<UserNftAddressBook> noticePage = userNftAddressBookService.page(page, new LambdaQueryWrapper<UserNftAddressBook>()
                .like(ObjectUtil.isNotEmpty(userNftAddressBook.getNftName()),UserNftAddressBook::getNftName, userNftAddressBook.getNftName())
                .like(ObjectUtil.isNotEmpty(userNftAddressBook.getNickName()),UserNftAddressBook::getNickName, userNftAddressBook.getNickName())
                .like(ObjectUtil.isNotEmpty(userNftAddressBook.getChannelName()),UserNftAddressBook::getChannelName, userNftAddressBook.getChannelName())
                .like(ObjectUtil.isNotEmpty(userNftAddressBook.getChannelCode()),UserNftAddressBook::getChannelCode, userNftAddressBook.getChannelCode())
                .eq(StrUtil.isNotEmpty(userNftAddressBook.getType()),UserNftAddressBook::getType, userNftAddressBook.getType())
                .eq(UserNftAddressBook::getStatus, 0).eq(UserNftAddressBook::getUserId, userNftAddressBook.getUserId()).orderByDesc(UserNftAddressBook::getCreateTime));
        return ServerResponseEntity.success(noticePage);
    }
    /**
     *
     * @param
     * @param id
     * @return
     */
    @GetMapping("/getOneById")
    @Operation(summary =  "获取详情", description = "获取详情")
    public ServerResponseEntity<UserNftAddressBook> getOneById(@RequestParam Long id) {
        UserNftAddressBook noticePage = userNftAddressBookService.getById(id);
        return ServerResponseEntity.success(noticePage);
    }
    /**
     *
     * @param
     * @param userNftAddressBook
     * @return
     */
    @PostMapping("/updateOneById")
    @Operation(summary =  "修改", description = "修改")
    public ServerResponseEntity updateOneById(@RequestBody UserNftAddressBook userNftAddressBook) {
        List<UserNftAddressBook> list = userNftAddressBookService.list(new LambdaQueryWrapper<UserNftAddressBook>()
                .eq(UserNftAddressBook::getNftCode, userNftAddressBook.getNftCode())
                .eq(UserNftAddressBook::getChannelCode, userNftAddressBook.getChannelCode())
                .eq(UserNftAddressBook::getStatus, 0).eq(UserNftAddressBook::getAdress, userNftAddressBook.getAdress()).eq(UserNftAddressBook::getUserId, userNftAddressBook.getUserId()));
        if(list.size()>1){
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create"));
        }else if(list.size()==1 && !list.get(0).getId().equals(userNftAddressBook.getId())){
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create"));
        }
        ChannelUserRelationRecord channelUserRelationRecord = channelUserRelationRecordService.getChannelAddressByaddress( userNftAddressBook.getAdress(),userNftAddressBook.getNftCode());
        if(!ObjectUtil.isNull(channelUserRelationRecord)){
            userNftAddressBook.setType("1");
            userNftAddressBook.setChannelUserId(channelUserRelationRecord.getUserId());
            User userByUserId = userService.getUserByUserId(channelUserRelationRecord.getUserId());
            if(!userNftAddressBook.getUserName().equals(userByUserId.getRealName())){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.realname"));
            }
        }else{
            List<BlockchainShop> oldBlockchainShopList = blockchainShopService.list(Wrappers.lambdaQuery(BlockchainShop.class).eq(BlockchainShop::getBlockchainCode, userNftAddressBook.getNftCode()).eq(BlockchainShop::getShopCode,userNftAddressBook.getChannelCode()));
            if(oldBlockchainShopList.size()==0||oldBlockchainShopList.get(0).getIsSynchronization()!=2){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.not.find"));
            }
            userNftAddressBook.setType("2");
            String url = shopConfig.getApiGatewayUrl() + "/personnft/outapi/app/user/getOutInfoAll?";
            Map<String, String> param = new HashMap<>();
            param.put("channelCode", userNftAddressBook.getChannelCode());
            param.put("chainCode", userNftAddressBook.getNftCode());
            param.put("address", userNftAddressBook.getAdress());
            JSONObject jsonObject = dataWebService.hutoolGetWebService(url, param,null,null);
            if(jsonObject.getInteger("code")!= Constant.SUCCESS_CODE){
                logger.info("获取{}",jsonObject.getString("msg"));
                throw new YamiShopBindException(jsonObject.getString("msg"));
            }
            if(jsonObject==null || jsonObject.getJSONObject("data")==null){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.not.find"));
            }
            if(!userNftAddressBook.getUserName().equals(jsonObject.getString("realName"))){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.realname"));
            }
            userNftAddressBook.setUpdateTime(new Date());
            userNftAddressBook.setChannelUserId(jsonObject.getString("userId"));
        }
        userNftAddressBookService.updateById(userNftAddressBook);
        return ServerResponseEntity.success();
    }

    /**
     *
     * @param
     * @param id
     * @return
     */
    @GetMapping("/deleteOneById")
    @Operation(summary =  "删除", description = "删除")
    public ServerResponseEntity deleteOneById(@RequestParam Long id) {
        userNftAddressBookService.removeById(id);
        return ServerResponseEntity.success();
    }

    /**
     *
     * @param
     * @param userNftAddressBook
     * @return
     */
    @PostMapping("/save")
    @Operation(summary =  "保存", description = "保存")
    public ServerResponseEntity save(@RequestBody UserNftAddressBook userNftAddressBook) {
        userNftAddressBook.setCreateTime(new Date());
        long count = userNftAddressBookService.count(new LambdaQueryWrapper<UserNftAddressBook>()
                .eq(UserNftAddressBook::getNftCode, userNftAddressBook.getNftCode())
                .eq(UserNftAddressBook::getChannelCode, userNftAddressBook.getChannelCode())
                .eq(UserNftAddressBook::getStatus, 0).eq(UserNftAddressBook::getAdress, userNftAddressBook.getAdress()).eq(UserNftAddressBook::getUserId, userNftAddressBook.getUserId()));
        if(count>0){
            return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create"));
        }
        //校验地址信息
        ChannelUserRelationRecord channelUserRelationRecord = channelUserRelationRecordService.getChannelAddressByaddress( userNftAddressBook.getAdress(),userNftAddressBook.getNftCode());
        if(!ObjectUtil.isNull(channelUserRelationRecord)){
            userNftAddressBook.setType("1");
            userNftAddressBook.setChannelUserId(channelUserRelationRecord.getUserId());
            User userByUserId = userService.getUserByUserId(channelUserRelationRecord.getUserId());
            if(!userNftAddressBook.getUserName().equals(userByUserId.getRealName())){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.realname"));
            }
        }else{
            List<BlockchainShop> oldBlockchainShopList = blockchainShopService.list(Wrappers.lambdaQuery(BlockchainShop.class).eq(BlockchainShop::getBlockchainCode, userNftAddressBook.getNftCode()).eq(BlockchainShop::getShopCode,userNftAddressBook.getChannelCode()));
            if(oldBlockchainShopList.size()==0||oldBlockchainShopList.get(0).getIsSynchronization()!=2){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.not.find"));
            }
            userNftAddressBook.setType("2");
            String url = shopConfig.getApiGatewayUrl() + "/personnft/outapi/app/user/getOutInfoAll?";
            Map<String, String> param = new HashMap<>();
            param.put("channelCode", userNftAddressBook.getChannelCode());
            param.put("chainCode", userNftAddressBook.getNftCode());
            param.put("address", userNftAddressBook.getAdress());
            JSONObject jsonObject = dataWebService.hutoolGetWebService(url, param,null,null);
            if(jsonObject.getInteger("code")!= Constant.SUCCESS_CODE){
                logger.info("获取{}",jsonObject.getString("msg"));
                throw new YamiShopBindException(jsonObject.getString("msg"));
            }
            if(jsonObject==null || jsonObject.getJSONObject("data")==null){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.not.find"));
            }
            if(!userNftAddressBook.getUserName().equals(jsonObject.getJSONObject("data").getString("realName"))){
                return ServerResponseEntity.showFailMsg(I18nMessage.getMessage("yami.channel.check.create.realname"));
            }
            userNftAddressBook.setChannelUserId(jsonObject.getJSONObject("data").getString("userId"));
        }
        userNftAddressBookService.save(userNftAddressBook);
        return ServerResponseEntity.success();
    }


    /**
     *转增保存地址簿
     * @param
     * @param userNftAddressBook
     * @return
     */
    @PostMapping("/saveAddressBook")
    @Operation(summary =  "保存", description = "保存")
    public ServerResponseEntity saveTwo(@RequestBody UserNftAddressBook userNftAddressBook) {
        Tuple<String> tuple = this.getChannelInfo(userNftAddressBook.getUserId());
        userNftAddressBook.setChannelCode(tuple.get(0));
        userNftAddressBook.setNftCode(tuple.get(2));
        userNftAddressBook.setType(tuple.get(3));
        long count = userNftAddressBookService.count(new LambdaQueryWrapper<UserNftAddressBook>()
                .eq(UserNftAddressBook::getNftCode, userNftAddressBook.getNftCode())
                .eq(UserNftAddressBook::getChannelCode, userNftAddressBook.getChannelCode())
                .eq(UserNftAddressBook::getStatus, 0)
                .eq(UserNftAddressBook::getType, userNftAddressBook.getType())
                .eq(UserNftAddressBook::getAdress, userNftAddressBook.getAdress())
                .eq(UserNftAddressBook::getUserId, userNftAddressBook.getUserId()));
        if(count==0){
            ShopDetail shopDetail = shopDetailService.getShopDetailByShopCode(userNftAddressBook.getChannelCode());
            Blockchain infoByCode = blockchainService.getInfoByCode(userNftAddressBook.getNftCode());
            userNftAddressBook.setUserId(userNftAddressBook.getUserId());
            userNftAddressBook.setAdress(userNftAddressBook.getAdress());
            userNftAddressBook.setChannelUserId(userNftAddressBook.getChannelUserId());
            userNftAddressBook.setNftCode(userNftAddressBook.getNftCode());
            userNftAddressBook.setNftName(infoByCode.getName());
            userNftAddressBook.setChannelCode(userNftAddressBook.getChannelCode());
            userNftAddressBook.setChannelName(shopDetail.getShopShortName());
            userNftAddressBook.setStatus(0);
            userNftAddressBook.setCreateTime(new Date());
            userNftAddressBook.setNickName(userNftAddressBook.getUserName());
            userNftAddressBook.setUserName(userNftAddressBook.getUserName());
            userNftAddressBookService.save(userNftAddressBook);
        }
        return ServerResponseEntity.success();
    }
}
